package bom.example.common.aop;

import com.alibaba.fastjson.JSONObject;
import bom.example.common.aop.annotation.Log;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/4/3 17:47
 * @since JDK 1.8
 */
@Aspect
@Slf4j
@Component
public class LogAopConfig {



    @Pointcut("@annotation(bom.example.common.aop.annotation.Log)")
    private void pointCut(){};

    @Around("pointCut()")
    public Object aroundJobConfig(ProceedingJoinPoint point) throws Throwable{
        Object result=null;
        String jobName="";

        Long start=System.currentTimeMillis();
        System.out.println("目标方法名为:" + point.getSignature().getName());
        System.out.println("目标方法所属类的简单类名:" +        point.getSignature().getDeclaringType().getSimpleName());
        System.out.println("目标方法所属类的类名:" + point.getSignature().getDeclaringTypeName());
        System.out.println("目标方法声明类型:" + Modifier.toString(point.getSignature().getModifiers()));

        //获取传入目标方法的参数
        Object[] args = point.getArgs();
        for (int i = 0; i < args.length; i++) {
            System.out.println("第" + (i+1) + "个参数为:" + args[i]);
        }
        String argJson= JSONObject.toJSONString(args);
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest req=attributes.getRequest();
        HttpServletResponse resp=attributes.getResponse();
        System.out.println("目标方法ip:" + req.getRequestURI());
        String restIp=req.getRequestURI();
        String restMethod=point.getSignature().getDeclaringType().getSimpleName();
        String resultObj="";
        Integer status=0;
        try {
            Class<?> cls=point.getTarget().getClass();
            String method=point.getSignature().getName();
            Method method1=getMethod(method,cls);
            Log log=method1.getDeclaredAnnotation(Log.class);
            jobName=log.value();
            result=point.proceed();
            if(result!=null){
                resultObj= JSONObject.toJSONString(result);
            }
        }catch (Exception e){
            log.info(jobName+"出现异常");
            resultObj= JSONObject.toJSONString(e.getMessage());
            status=1;
        }
        String ip=getRemoteAddr(req);
        Long end=System.currentTimeMillis();
        Long time=end-start;
        Integer t=Integer.valueOf(String.valueOf(time));
        log.info(jobName+"  执行完毕 耗时："+(end-start)+" ms");
        return result;
    }





    public Method getMethod(String method,Class<?> cls){
        Method[] methods=cls.getDeclaredMethods();
        int size=methods.length;
        for (int i = 0; i < size; i++) {
            Method method1=methods[i];
            if(!method1.getName().equals(method)){
                continue;
            }
            return method1;
        }
        return null;
    }

    public static String getRemoteAddr(HttpServletRequest request) {
        log.info("x-forwarded-for"+request.getHeader("x-forwarded-for"));
        log.info("x-forwarded-for"+request.getHeader("WL-Proxy-Client-IP"));
        log.info("x-forwarded-for"+request.getHeader("WL-Proxy-Client-IP"));
        log.info("x-forwarded-for"+request.getRemoteAddr());
        //
        String userName = request.getParameter("userName");
        log.info("x-forwarded-for" + userName );
        if(StringUtils.hasText(userName)){
            return userName;
        }

        String ip = request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        if (ip.contains(",")) {
            return ip.split(",")[0];
        } else {
            return ip;
        }
    }
}
